package com.my.core.util.code;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 流水号生成规则(按默认规则递增，数字从1-99开始递增，数字到99，递增字母;位数不够增加位数)
 * A001
 * A001A002
 *
 * @Author zhangdaihao
 */
public class CodeUtil {

    // 数字位数(默认生成3位的数字)

    private static final int numLength = 2;//代表数字位数

    public static final int zhanweiLength = 1 + numLength;
    /**
     * 获取随机字符,自定义长度
     *
     * @author fengshuonan
     * @Date 2018/3/18 21:55
     */
    public static String getRandomString(int length) {
        String base = "abcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }
    /**
     * 组合编码
     *   //[A07, A07A01, A07A01A01, A07A01A01A03, A07A01A01A03A02, A07A01A01A03A02A08, A07A01A01A03A02A08A03]
     *         String test = "A07A01A01A03A02A08A03";
     * @param string
     * @return
     */
    public static List<String> getCodesGroups(String string){
        List<String> strs = new ArrayList<String>();
        int z = 0;
        for(int i=0;i<string.length()/3;i++){
            String a = string.substring(z,z+3);
            strs.add(a);
            z = z+3;
        }
        List<String> returnStrs = new ArrayList<String>();
        StringBuffer str = new StringBuffer();
        strs.forEach(x->{
            StringBuffer append = str.append(x);
            returnStrs.add(append.toString());
        });
        return returnStrs;
    }

    /**
     * 根据前一个code，获取同级下一个code
     * 例如:当前最大code为D01A04，下一个code为：D01A05
     *
     * @param code
     * @return
     */
    public static synchronized String getNextYouBianCode(String code) {
        String newcode = "";
        if (code == null || code == "") {
            String zimu = "A";
            String num = getStrNum(1);
            newcode = zimu + num;
        } else {
            String before_code = code.substring(0, code.length() - 1 - numLength);
            String after_code = code.substring(code.length() - 1 - numLength, code.length());
            char after_code_zimu = after_code.substring(0, 1).charAt(0);
            Integer after_code_num = Integer.parseInt(after_code.substring(1));

            String nextNum = "";
            char nextZimu = 'A';
            // 先判断数字等于999*，则计数从1重新开始，递增
            if (after_code_num == getMaxNumByLength(numLength)) {
                nextNum = getNextStrNum(0);
            } else {
                nextNum = getNextStrNum(after_code_num);
            }
            // 先判断数字等于999*，则字母从A重新开始,递增
            if (after_code_num == getMaxNumByLength(numLength)) {
                nextZimu = getNextZiMu(after_code_zimu);
            } else {
                nextZimu = after_code_zimu;
            }

            // 例如Z99，下一个code就是Z99A01
            if ('Z' == after_code_zimu && getMaxNumByLength(numLength) == after_code_num) {
                newcode = code + (nextZimu + nextNum);
            } else {
                newcode = before_code + (nextZimu + nextNum);
            }
        }
        return newcode;

    }
    /*-----------------------------------------上一个方法的封装包开始------------------------------------------------------*/
    /**
     * 根据父亲code,获取下级的下一个code
     * <p>
     * 例如：父亲CODE:A01
     * 当前CODE:A01B03
     * 获取的code:A01B04
     *
     * @param parentCode 上级code
     * @param localCode  同级code
     * @return
     */
    public static synchronized String getSubYouBianCode(String parentCode, String localCode) {
        if (localCode != null && localCode != "") {

//			return parentCode + getNextYouBianCode(localCode);
            return getNextYouBianCode(localCode);

        } else {
            parentCode = parentCode + "A" + getNextStrNum(0);
        }
        return parentCode;
    }


    /**
     * 将数字前面位数补零
     *
     * @param num
     * @return
     */
    private static String getNextStrNum(int num) {
        return getStrNum(getNextNum(num));
    }

    /**
     * 将数字前面位数补零
     *
     * @param num
     * @return
     */
    private static String getStrNum(int num) {
        String s = String.format("%0" + numLength + "d", num);
        return s;
    }

    /**
     * 递增获取下个数字
     *
     * @param num
     * @return
     */
    private static int getNextNum(int num) {
        num++;
        return num;
    }

    /**
     * 递增获取下个字母
     *
     * @return
     */
    private static char getNextZiMu(char zimu) {
        if (zimu == 'Z') {
            return 'A';
        }
        zimu++;
        return zimu;
    }

    /**
     * 根据数字位数获取最大值
     *
     * @param length
     * @return
     */
    private static int getMaxNumByLength(int length) {
        if (length == 0) {
            return 0;
        }
        String max_num = "";
        for (int i = 0; i < length; i++) {
            max_num = max_num + "9";
        }
        return Integer.parseInt(max_num);
    }
    /*-----------------------------------------------------------------------------------------------*/

    public static void main(String[] args) {
        // org.jeecgframework.core.util.LogUtil.info(getNextZiMu('C'));
        // org.jeecgframework.core.util.LogUtil.info(getNextNum(8));
        // org.jeecgframework.core.util.LogUtil.info(cutYouBianCode("C99A01B01")[2]);
    }

    //数字转字母 1-26 ： A-Z
    private String numberToLetter(int num) {
        if (num <= 0) {
            return null;
        }
        String letter = "";
        num--;
        do {
            if (letter.length() > 0) {
                num--;
            }
            letter = ((char) (num % 26 + (int) 'A')) + letter;
            num = (int) ((num - num % 26) / 26);
        } while (num > 0);

        return letter;
    }
    //字母转数字  A-Z ：1-26
    public int letterToNumber(String letter) {
        int length = letter.length();
        int num = 0;
        int number = 0;
        for(int i = 0; i < length; i++) {
            char ch = letter.charAt(length - i - 1);
            num = (int)(ch - 'A' + 1) ;
            num *= Math.pow(26, i);
            number += num;
        }
        return number;
    }
}
